package sifa;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.thunlp.text.classifiers.BasicTextClassifier;
import org.thunlp.text.classifiers.ClassifyResult;
import org.thunlp.text.classifiers.LinearBigramChineseTextClassifier;

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;


public class DataProcess {
    private static String pathPredix = "/Users/wengjunjie/PycharmProjects/THUCTC/dataQingXi";

    public static void main(String args[]) {
        dataToText();
        // String s = "{\"caseCause\": \"抢劫罪\", \"justice\": \"经审理查明，被告人马某某于2016年2月22日凌晨2时许，伙同马XXX、马XX（均已判决），在兰州市城关区中山路\"\\\"亚欧商厦\"楼下的地下通道口附近，对被害人姚家琪殴打后，劫取其红米牌（NOTE3）手机一部，实物价值人民币1261元，MIXBOX女士钱包一只，内装现金300余元，身份证、学生证、工商银行卡一张。作案后，被告人等人将所抢身份证、学生证、银行卡丢弃，赃款共同挥霍。破案后，追回被抢手机，已发还被害人。\\n\", \"opinion\": \"本院认为，被告人马某某无视刑律，伙同他人一起抢劫公民财物，其行为已构成抢劫罪。公诉机关指控被告人马某某犯抢劫罪的事实和罪名成立，本院予以确认。同时考虑到被告人归案后能如实供述自己的犯罪事实，可以从轻处罚。为维护社会治安秩序，保护公民的人身及财产权利不受侵犯，惩罚犯罪。依照《中华人民共和国刑法》第二百六十三条、第二十五条一款、第六十七条三款之规定，\", \"province\": \"甘肃省\", \"judge\": 36, \"filename\": \"23612736\"}";
        // s = replaceHtml(s);
        //  runTrainAndTest();
        //	  runLoadModelAndUse();
        // AddFilesManuallyAndTrain();
    }

    private static void dataToText() {
        // /Users/wengjunjie/works/人工智能/11data/1632652922606/刑期预测赛道一期数据_训练
        String path = "/Users/wengjunjie/works/人工智能/11data/1632652922606/train.txt";
        try {
            List<String> scanListPath = readFile02(path);
            int i = 0;
            for (String s : scanListPath) {
                s = replaceHtml(s);
                JSONObject jsonObject = JSON.parseObject(s);
                int judge = jsonObject.getInteger("judge");
                int filename = jsonObject.getInteger("filename");
                String caseCause = jsonObject.getString("caseCause");
                String justice = jsonObject.getString("justice");
                System.out.println(i++ + "..caseCause=" + justice);
                String opinion = jsonObject.getString("opinion");
                String province = jsonObject.getString("province");
                File folder = new File(pathPredix + "/" + judge);
                if (!folder.exists() && !folder.isDirectory()) {
                    folder.mkdirs();
                    System.out.println("创建文件夹");
                }
                //放大50倍  非法持有、私藏枪支、弹药罪
                int forNum = 1;
                if (caseCause.equals("非法持有、私藏枪支、弹药罪")) {
                    forNum = 1 + 50;
                }
                for (int j = 0; j < forNum; j++) {
                    File file = new File(pathPredix + "/" + judge + "/" + filename + "_" + j + ".txt");
                    String justiceTmp = buildData(justice);
                    String opinionTmp = buildData(opinion);
                    if (!file.exists()) {
                        try {
                            file.createNewFile();
                            FileWriter fw = new FileWriter(file);
                            fw.write(caseCause + ",\r\n");
                            fw.write(justiceTmp + ",\r\n");
                            fw.write(opinionTmp + ",\r\n");
                            fw.write(province + ",\r\n");

                            fw.flush();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }

            }
            System.out.println("aa");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static String buildData(String justice) {
        //https://blog.csdn.net/qq_27590277/article/details/120232244
        String res = justice;
        String[] zifurray = {".", ";", "?", ";", "!", "."};
        for (String s : justice.split("[： ， ； 。]")) {
            StringBuffer s1 = new StringBuffer(s);
            if (s.length() > 10) {
                // System.out.println(s);
                int ran1 = (int) (Math.random() * (s.length() / 3 - 1) + 1);
                int start = (int) (Math.random() * (ran1 - 1) + 1);
                for (int i = 0; i < ran1; i++) {
                    //总数里面取 ran1个随机数
                    int starAyyay = (int) (Math.random() * (zifurray.length));
                    s1.insert(start, zifurray[starAyyay]);
                    start = (int) (Math.random() * (s1.length() - start) + start);
                }
            }
            res = res.replace(s, s1.toString());
        }
        return res;
    }

    private static String replaceHtml(String s) {
        //{"caseCause": "非法经营罪", "justice": "经审理查明，2011年至2013年，王×担任VICTORYMARKETINGLIMITED大中华区市场部总监、北京中夏融通国际教育咨询有限公司（办公地点为：北京市朝阳区建外SOHO16号楼1706号）负责人，让客户下载并注册未经批准的"VFX"平台，并以此经营炒黄金、外汇期货的业务，金额达人民币30万余元。被告人王×后被抓获归案。\n2013年8月8日，梁XX的投资款是124000人民币（2万美元），当时只汇了15400美元至王×香港汇丰银行卡上（×××），剩下的钱用于员工发工资了。王×给了我一个平台卡号（711026），让我进行交易。\n2013年11月27日，徐×通过建设银行投入20300美金至王×建设银行。2014年1月，徐×要求终止交易，王×说平台上的钱他自己用了，无法还给我和徐×。王×给我们打了一个欠条。\n2013年11月29日至2014年1月20日，户名为"jinhaixu"的客户在"VFXTraher"系统的操作情况，买入了"gbpusd、xauusd、eurusd、audusd、"。\n2012年5月26日，王×在香港汇丰银行以自己名义开立的"VictoryMarketingLtd"的账户（×××）资金往来情况，其中2013年8月9日存入美元15391.6元，2013年11月27日存入美元19984.06元。\n2011年7月左右，倪×让我在新西兰注册"VFX奥X国际"国际炒汇、炒黄金平台，网址"www。vmarkets。net"。VFX奥X国际的网站是倪×找人设计的。奥盛国际公司大中华区市场部总监的聘书是倪×给我的。倪×给我们一个监管账户可以看到客户购买的产品。中夏融通公司和元丰投资、营口百信都是VFX奥X国际的代理商。该平台能够链接FXDD马耳他交易商和LAMAX英国交易所。\n",
        // "opinion": "本院认为，被告人王×法制观念淡薄，违反国家规定，未经国家有关主管部门批准非法经营买卖黄金、外汇的期货业务，其行为已构成非法经营罪，依法应予惩处。北京市朝阳区人民检察院指控被告人王×犯非法经营罪的事实清楚，证据确实、充分，指控的罪名成立；唯指控的犯罪数额有误，本院根据现有证据依法予以变更。被告人王×关于自己没有非法经营的辩护意见，及其辩护人关于本案证据不足的辩护意见，缺乏事实依据，本院不予采纳。综上，根据被告人王×犯罪的事实、犯罪的性质、情节以及对于社会的危害程度，本院依照《中华人民共和国刑法》第二百二十五条、第六十一条、第四十五条、第四十七条、第五十二条、第五十三条之规定，",
        // "province": "北京市", "judge": 6, "filename": "18430542"}
        String tmp = s.split("justice")[1];
        String justice = tmp.split("opinion")[0];
        justice = justice.substring(4, justice.length() - 4);
        String justice2 = justice.replaceAll("\"", "");
        justice2 = justice2.replaceAll("\\\\", "");
        s = s.replace(justice, justice2);

        tmp = s.split("opinion")[1];
        String opinion = tmp.split("province")[0];
        opinion = opinion.substring(4, opinion.length() - 4);
        String opinion2 = opinion.replaceAll("\"", "");
        opinion2 = opinion2.replaceAll("\\\\", "");
        s = s.replace(opinion, opinion2);

        JSONObject json = JSONObject.parseObject(s);
        return s;
    }

    /**
     * 读取一个文本 一行一行读取
     *
     * @param path
     * @return
     * @throws IOException
     */
    public static List<String> readFile02(String path) throws IOException {
        // 使用一个字符串集合来存储文本中的路径 ，也可用String []数组
        List<String> list = new ArrayList<String>();
        FileInputStream fis = new FileInputStream(path);
        // 防止路径乱码   如果utf-8 乱码  改GBK     eclipse里创建的txt  用UTF-8，在电脑上自己创建的txt  用GBK
        InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
        BufferedReader br = new BufferedReader(isr);
        String line = "";
        while ((line = br.readLine()) != null) {
            // 如果 t x t文件里的路径 不包含---字符串       这里是对里面的内容进行一个筛选
            if (line.lastIndexOf("---") < 0) {
                list.add(line);
            }
        }
        br.close();
        isr.close();
        fis.close();
        return list;
    }

    /**
     * 如果需要对一批文本进行训练，再进行测试，可以按照本函数的代码调用分类器
     */
    public static void runTrainAndTest() {

        // 新建分类器对象
        BasicTextClassifier classifier = new BasicTextClassifier();

        // 设置参数
        String defaultArguments = ""
                + "-train  " + pathPredix + " "  // 设置您的训练路径，这里的路径只是给出样例
                + "-test   " + pathPredix + " "
                //	+ "-l C:\\Users\\do\\workspace\\TestJar\\my_novel_model "
                //	+ "-cdir E:\\Corpus\\书库_cleared "
                //	+ "-n 1 "
                // + "-classify E:\\Corpus\\书库_cleared\\言情小说 "  // 设置您的测试路径。一般可以设置为与训练路径相同，即把所有文档放在一起。
                + "-d1 0.7 "  // 前70%用于训练
                + "-d2 0.3 "  // 后30%用于测试*/
                + "-f 50000 " // 设置保留特征数，可以自行调节以优化性能
                + "-s ./my_novel_model3"  // 将训练好的模型保存在硬盘上，便于以后测试或部署时直接读取模型，无需训练
                ;

        // 初始化
        classifier.Init(defaultArguments.split(" "));

        // 运行
        classifier.runAsBigramChineseTextClassifier();

    }


    /**
     * 如果需要读取已经训练好的模型，再用其进行分类，可以按照本函数的代码调用分类器
     */
    public static void runLoadModelAndUse() {
        // 新建分类器对象
        BasicTextClassifier classifier = new BasicTextClassifier();

        // 设置分类种类，并读取模型
        classifier.loadCategoryListFromFile("my_novel_model/category");
        classifier.setTextClassifier(new LinearBigramChineseTextClassifier(classifier.getCategorySize()));
        classifier.getTextClassifier().loadModel("my_novel_model");

		/*
		 * 上面三行代码等价于设置如下参数，然后初始化并运行：
		 *
		   String defaultArguments = ""
		 +  "-l  my_novel_model"  // 设置您的训练好的模型的路径，这里的路径只是给出样例
		 ;
		 classifier.Init(defaultArguments.split(" "));
		 classifier.runAsLinearBigramChineseTextClassifier();
		 *
		 */

        // 之后就可以使用分类器进行分类
        String text = "我喜欢踢足球";
        int topN = 3;  // 保留最有可能的3个结果
        ClassifyResult[] result = classifier.classifyText(text, topN);
        for (int i = 0; i < topN; ++i) {
            // 输出分类编号，分类名称，以及概率值。
            System.out.println(result[i].label + "\t" +
                    classifier.getCategoryName(result[i].label) + "\t" +
                    result[i].prob);
        }
    }

    /**
     * 如果需要按照特殊需求自行添加训练文件，可以按照本函数的代码调用分类器
     */
    public static void AddFilesManuallyAndTrain() {

        // 新建分类器对象
        BasicTextClassifier classifier = new BasicTextClassifier();

        // 设置分类种类
        classifier.loadCategoryListFromFile("在此输入您的类型列表文件的路径，例如  /media/disk2/data/novel/category.lst");
        classifier.setTextClassifier(new LinearBigramChineseTextClassifier(classifier.getCategorySize()));

		/*
		 * 上面两行代码等价于设置如下参数，然后初始化：
		 *
		   String defaultArguments = ""
		 + "-c /media/disk2/data/novel/category_list "  // 设置您的类型列表文件的路径
		 ;
		 classifier.Init(defaultArguments.split(" "));
		 *
		 */

        // 手动添加文件的方法。每个训练文件按照下面的接口调用一次。
        String filepath = "在此输入您的一个训练文件路径";
        String category = "在此输入训练文件对应的类型名称";
        if (!classifier.addTrainingText(category, filepath)) {
            System.out.println("添加训练文件失败。文件路径为：" + filepath);
            return;
        }

        // 训练并保存模型
        classifier.getTextClassifier().train();
        classifier.getTextClassifier().saveModel("在此输入您保存的模型的路径，例如  /media/disk2/data/novel/my_novel_model");

    }


}
